package com.lvy.hczn.front.business.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lvy.hczn.front.business.common.Constants;
import com.lvy.hczn.front.business.dto.Param;
import com.lvy.hczn.front.business.dto.SearchCondition;
import com.lvy.hczn.front.business.dto.SortTaskDetailDto;
import com.lvy.hczn.front.business.service.*;
import com.lvy.hczn.front.business.util.ResultUtil;
import com.lvy.hczn.front.common.core.controller.BaseController;
import com.lvy.hczn.front.common.core.domain.AjaxResult;
import com.lvy.hczn.front.common.core.domain.BaseModel;
import com.lvy.hczn.front.common.core.redis.RedisCache;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.system.domain.system.SysStudent;
import com.lvy.hczn.mq.rocket.ParamInfo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/dt/test/")
@Slf4j
public class TestFrontController extends BaseController {

    @Autowired
    private WarehousingEntryService warehousingEntryService;

    @Autowired
    private AccessManagerService accessManagerService;

    @Autowired
    private PurchaseOrderService purchaseOrderService;

    @Autowired
    private SortTaskDetailService sortTaskDetailService;

    @Autowired
    private OutboundOrderService outboundOrderService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private SaleOrderDetailService saleOrderDetailService;

    @Autowired
    private SaleOrderService saleOrderService;

    @Autowired
    private PurchaseOrderDetailService purchaseOrderDetailService;

    @Autowired
    private GoodsBoxDetailService goodsBoxDetailService;

    @Autowired
    private WcsService wcsService;

    @Autowired
    private GoodsBoxService goodsBoxService;

    @Autowired
    private WarehouseBoxEntryService warehouseBoxEntryService;

    /**
     * 入库单/出库单同步平台
     *
     * @param info
     * @return
     */
    @ApiOperation(value = "入库单/出库单同步平台", notes = "入库单/出库单同步平台")
    @PostMapping("entry")
    public AjaxResult entry(HttpServletRequest request, @RequestBody ParamInfo<WarehousingEntry> info) {
        try {
            warehousingEntryService.commitToPlatform(info.getData(), false, true);
            return AjaxResult.success();
        } catch (Exception e) {
            if (e instanceof UtilException) {
                return AjaxResult.error(e.getMessage());
            } else {
                log.error("sale同步异常：{}", e);
                return AjaxResult.error("系统异常");
            }
        }
    }

    /**
     * 门禁通知
     *
     * @param info
     * @return
     */
    @ApiOperation(value = "门禁通知", notes = "入库单/出库单同步平台")
    @PostMapping("access")
    public AjaxResult access(HttpServletRequest request, @RequestBody ParamInfo<AccessManager> info) {
        try {
            if (StrUtil.isEmpty(info.getData().getAccessCode())) {
                throw new UtilException("门禁编号为空");
            }
            AccessManager accessManager = accessManagerService.getOne(Wrappers.<AccessManager>lambdaQuery().eq(AccessManager::getAccessCode, info.getData().getAccessCode()).orderByDesc(BaseModel::getCreateTime).last("limit 1"));
            accessManagerService.accessManagerCode(accessManager, false);
            return AjaxResult.success();
        } catch (Exception e) {
            if (e instanceof UtilException) {
                return AjaxResult.error(e.getMessage());
            } else {
                log.error("sale同步异常：{}", e);
                return AjaxResult.error("系统异常");
            }
        }
    }

    /**
     * 门禁通知
     *
     * @param info
     * @return
     */
    @ApiOperation(value = "调拨出库分拣完成", notes = "调拨出库分拣完成")
    @PostMapping("transferSortDone")
    public AjaxResult transferSortDone(HttpServletRequest request, @RequestBody ParamInfo info) {
        try {
            SortTask sortTask = JSON.parseObject(JSON.toJSONString(info.getData()), SortTask.class);
            if (StrUtil.isEmpty(sortTask.getAssociatedOrderCode())) {
                throw new UtilException("关联订单号不能为空");
            }
            sortTaskDetailService.sendSortTransferDoneToPlatform(null, null, sortTask);
            return AjaxResult.success();
        } catch (Exception e) {
            if (e instanceof UtilException) {
                return AjaxResult.error(e.getMessage());
            } else {
                log.error("transferSortDone同步异常：{}", e);
                return AjaxResult.error("系统异常");
            }
        }
    }

    @ApiOperation(value = "提交入库单到平台", notes = "提交入库单到平台")
    @PostMapping("commitToPlatformInfo")
    public ResultUtil commitToPlatformInfo(@RequestBody Param param) {
        try {
            warehousingEntryService.commitToPlatformInfo(param, param.getEntryCode(), param.isOutboundAndEntry());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("commitToPlatformInfo:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                e.printStackTrace();
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "仓库出库后，提交出库单到平台", notes = "提交入库单到平台")
    @PostMapping("warehouseOut")
    public ResultUtil warehouseOut(@RequestBody Param param) {
        try {
            outboundOrderService.clearOutboundCodeByClient(param);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("warehouseOut:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                e.printStackTrace();
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "redis设置值", notes = "redis设置值")
    @PostMapping("redis/set")
    public ResultUtil warehouseOut(@RequestBody Map<String, Object> map) {
        try {
            String key = "key";
            String value = "value";
            if (map == null) {
                throw new UtilException("数据信息为空");
            }
            if (!map.containsKey(key) || !map.containsKey(value)) {
                throw new UtilException("key或value不存在");
            }
            if (map.get("key").toString().equals("") || map.get("value").toString().equals("")) {
                throw new UtilException("key或value为空");
            }
            redisCache.set(map.get("key").toString(), map.get("value").toString());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("redis/set:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                e.printStackTrace();
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 配送单-分拣任务完成通知
     *
     * @param paramInfo
     */
    @PostMapping(value = "sort/done")
    public void sendSortDoneToPlatform(@RequestBody ParamInfo paramInfo) {
        SortTaskDetail sortTaskDetail = JSON.parseObject(JSON.toJSONString(paramInfo.getData()), SortTaskDetail.class);
        sortTaskDetailService.sendSortDoneToPlatform(sortTaskDetail, Constants.SORT_TASK_DETAIL_DONE, false);
    }

    @ApiOperation(value = "模拟分拣", notes = "模拟分拣")
    @PostMapping("updateSortWeightById")
    private ResultUtil updateSortWeightById(HttpServletRequest request, @RequestBody SortTaskDetailDto sortTaskDetail) {
        try {
            Map<String, Object> map = sortTaskDetailService.updateSortWeightById(request, sortTaskDetail, sortTaskDetail.getBoxCode(), sortTaskDetail.getSortIds());
            return ResultUtil.ok(map);
        } catch (Exception e) {
            log.error("updateSortWeightById:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @ApiOperation(value = "销售退货入库(未发货取消入库)", notes = "销售退货入库(未发货取消入库)")
    @PostMapping("returnEntry")
    private ResultUtil returnEntry(@RequestBody SaleOrderDetail saleOrderDetail) {
        try {
            List<SaleOrderDetail> saleOrderDetailList = saleOrderDetailService.list(Wrappers.<SaleOrderDetail>lambdaQuery().eq(SaleOrderDetail::getSaleOrderCode, saleOrderDetail.getSaleOrderCode()).eq(SaleOrderDetail::getDataType, saleOrderDetail.getDataType()).eq(SaleOrderDetail::getStatus, saleOrderDetail.getStatus()));
            SaleOrder saleOrder = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSaleOrderCode, saleOrderDetail.getSaleOrderCode()).eq(SaleOrder::getType, saleOrderDetail.getRemark()));
            saleOrderDetailList.forEach(detail -> {
                WarehousingEntry warehousingEntry = new WarehousingEntry();
                warehousingEntry.setEntryCode(detail.getSaleOrderCode());
                warehousingEntry.setServiceCode(saleOrder.getServiceCode());
                warehousingEntry.setSourceId(saleOrder.getSourceId());
                warehousingEntry.setDataType(detail.getDataType());
                warehousingEntry.setWarehouseCode(saleOrder.getWarehouseCode());
                warehousingEntry.setSpuId(detail.getSpuId());
                warehousingEntry.setSkuCode(detail.getSkuCode());
                warehousingEntry.setSpecCode(detail.getSpecCode());
                warehousingEntry.setQuantity(detail.getQuantity());
                warehousingEntry.setUnit(detail.getUnit());
                warehousingEntry.setWeight(detail.getWeight());
                warehousingEntry.setSupplierCode(detail.getSupplierCode());
                warehousingEntry.setBatchCode(detail.getBatchCode());
                warehousingEntry.setStatus("0");
                WarehousingEntry entry = warehousingEntryService.getOne(Wrappers.<WarehousingEntry>lambdaQuery().eq(WarehousingEntry::getDataType, com.lvy.hczn.front.common.constant.Constants.WAREHOUSING_ENTRY_DATA_TYPE_EIGHT).eq(WarehousingEntry::getSpuId, detail.getSpuId()).eq(WarehousingEntry::getSkuCode, detail.getSkuCode()).last("limit 1"));
                if (entry != null) {
                    warehousingEntry.setProducerId(entry.getProducerId());
                    warehousingEntry.setWarrantyDate(entry.getWarrantyDate());
                    warehousingEntry.setPickTime(entry.getPickTime());
                }
                warehousingEntryService.save(warehousingEntry);
            });
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("returnEntry:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 强制入库,入货箱重量与称重不匹配
     *
     * @param param
     * @return
     */
    @ApiOperation(value = "强制入库", notes = "强制入库")
    @PostMapping("entryForce")
    public ResultUtil entryForce(@Valid @RequestBody Param param) {
        try {
            log.error("强制入库参数：" + JSONUtil.toJsonStr(param));
            wcsService.entryForceInfo(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("entryForce:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    /**
     * 退货拒收入回调
     *
     * @return
     */
    @PostMapping("return/back")
    @ApiOperation(value = "退货拒收入回调", notes = "退货拒收入库离开缓存位回调业务处理")
    public ResultUtil returnCallBack(@RequestBody SearchCondition param) {
        saleOrderService.returnCallBack(param);
        return ResultUtil.ok();
    }

    /**
     * 退货拒收入回调
     *
     * @return
     */
    @PostMapping("shelf/location")
    @ApiOperation(value = "出入库调整库位", notes = "出入库调整库位")
    public ResultUtil shelfLocation(@RequestBody SearchCondition param) {
        GoodsBox goodsBox = goodsBoxService.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, param.getBoxCode()));
        List<GoodsBox> list = new ArrayList<>();
        list.add(goodsBox);
        warehousingEntryService.boxShelfLocationMsg(null, list, true);
        return ResultUtil.ok();
    }

    @ApiOperation(value = "空箱出入库单", notes = "空箱出入库单")
    @PostMapping("boxEmptyLease")
    public ResultUtil boxEmptyLease(@RequestBody WarehouseBoxEntry warehouseBoxEntry) {
        try {
            log.error("空箱出入库单：" + JSONUtil.toJsonStr(warehouseBoxEntry));
            warehouseBoxEntryService.syncToDataTransmit(warehouseBoxEntry);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("entryForce:{}", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                return ResultUtil.failed("系统异常");
            }
        }
    }

    public static void main(String[] args) {
        List<SysStudent> personList = new ArrayList<>();
        personList.add(new SysStudent("李四1", 65L));
        personList.add(new SysStudent("张三", 20L));
        personList.add(new SysStudent("李四", 25L));
        personList.add(new SysStudent("张三", 20L));
        personList.add(new SysStudent("张三丰", 30L));
        personList.add(new SysStudent("王五", 35L));
        personList.add(new SysStudent("张三", 20L));

        List<SysStudent> distinctPersonList = personList.stream()
                .collect(Collectors.toCollection(LinkedHashSet::new))
                .stream()
                .collect(Collectors.toList());

        distinctPersonList.forEach(person -> System.out.println(person.getStudentName() + ", " + person.getStudentId()));

        List<SysStudent> lastDownloadListOfUnique = personList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SysStudent::getStudentName))), ArrayList::new));
        System.out.println("********************************************");
        lastDownloadListOfUnique.forEach(item -> System.out.println(item.getStudentName() + ", " + item.getStudentId()));

        System.out.println("********************************************");
        LinkedHashMap<Object, Boolean> map1 = new LinkedHashMap<>();
        List<SysStudent> downloadListOfUnique = personList.stream().filter(i -> map1.putIfAbsent(i.getStudentId(), Boolean.TRUE) == null).collect(Collectors.toList());
        downloadListOfUnique.forEach(item -> System.out.println(item.getStudentName() + ", " + item.getStudentId()));
    }

    @PostMapping("purchase")
    public ResultUtil purchase(@Valid @RequestBody Param param) {
        try {
            log.error("采购入库测试参数：" + JSONUtil.toJsonStr(param));
            wcsService.productEntry(param, param.getUpOrDownPolicy());
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("purchase:", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                log.error("purchase:", e);
                return ResultUtil.failed("系统异常");
            }
        }
    }

    @RequestMapping("/receipt")
    public ResultUtil printReceipt(@RequestBody SortTaskDetail sortTaskDetail) {
        try {
            sortTaskDetailService.printReceipt(sortTaskDetail);
            return ResultUtil.ok();
        } catch (Exception e) {
            log.error("printReceipt:", e);
            if (e instanceof UtilException) {
                return ResultUtil.failed(e.getMessage());
            } else {
                log.error("printReceipt:", e);
                return ResultUtil.failed("系统异常");
            }
        }
    }
}
